﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace CarolLib.KVCompare
{
    public partial class frmMain : Form, ISaver
    {
        private Dictionary<string, string> dicA { get; set; }
        private Dictionary<string, string> dicB { get; set; }
        private List<KeyValuePair<string, string>> onlyA { get; set; }
        private List<KeyValuePair<string, string>> onlyB { get; set; }
        private List<KeyValuePair<string, string>> diff { get; set; }

        private string FileA;
        private string FileB;

        private const string FILE_NAME = "Only in {0}";
        private const string FILE_NAME_AB = "Different between {0} and {1}";

        private const int HEIGHT_MIN = 137;
        private const int HEIGHT_MAX = 300;

        List<Control> listControls;
        public frmMain()
        {
            InitializeComponent();
            listControls = new List<Control>();
            foreach (Control control in this.Controls)
            {
                listControls.Add(control);
            }

            this.Height = HEIGHT_MIN;
        }

        private void buttonChoose_Click(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.listControls.Where(c => c.Name == "textBox" + (sender as Button).Tag.ToString()).First().Text = this.openFileDialog1.FileName;
                
                if ((sender as Button).Tag.ToString()=="1")
                    this.FileA = this.openFileDialog1.SafeFileName;
                else
                    this.FileB = this.openFileDialog1.SafeFileName;

                this.openFileDialog1.FileName = string.Empty;
                return;
            }
        }

        private void buttonCompare_Click(object sender, EventArgs e)
        {
            try
            {
                dicA = GetKVs(textBox1.Text.Trim());
                dicB = GetKVs(textBox2.Text.Trim());

                onlyA = dicA.Where(p => !dicB.ContainsKey(p.Key)).ToList();
                onlyB = dicB.Where(p => !dicA.ContainsKey(p.Key)).ToList();
                diff = dicA.Where(p => (dicB.ContainsKey(p.Key)) && (p.Value != dicB[p.Key])).ToList();

                this.lbA.Text = dicA.Count.ToString();
                this.lbB.Text = dicB.Count.ToString();
                this.lbOnlyA.Text = onlyA.Count.ToString();
                this.lbOnlyB.Text = onlyB.Count.ToString();
                this.lbDiff.Text = diff.Count.ToString();
            }
            catch
            {
                MessageBox.Show("Please Choose two CVS files to compare.");
                return;
            }

            this.Height = HEIGHT_MAX;
        }

        private Dictionary<string, string> GetKVs(string path)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            using (StreamReader f1 = new StreamReader(path, System.Text.Encoding.Default))
            {
                while (!f1.EndOfStream)
                {
                    string line = f1.ReadLine();
                    string[] kv = line.Split(',');
                    if (kv.Count() > 1)
                    {
                        dic.Add(kv[0], line.Substring(kv[0].Length + 1));
                    }
                    else
                    {
                        dic.Add(line, string.Empty);
                    }
                }
            }
            return dic;
        }

        private void buttonView_Click(object sender, EventArgs e)
        {
            string fileName;
            List<KeyValuePair<string, string>> data = null;

            switch ((sender as Button).Tag.ToString())
            {
                case "A":
                    {
                        fileName = string.Format(FILE_NAME, FileA);
                        data = onlyA;
                    }
                    break;
                case "B":
                    {
                        fileName = string.Format(FILE_NAME, FileB);
                        data = onlyB;
                    }
                    break;
                default:
                    {
                        fileName = string.Format(FILE_NAME_AB, FileA, FileB);
                        data = new List<KeyValuePair<string,string>>();
                        diff.ForEach(p => data.Add(new KeyValuePair<string,string>(p.Key,string.Format("{0}::{1}", p.Value, dicB[p.Key]))));
                    }
                    break;
            }

            frmGrid grid = new frmGrid(fileName, data, (sender as Button).Tag.ToString(), this);
            grid.ShowDialog();
        }

        public void buttonSave_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            string fileName;

            switch ((sender as Button).Tag.ToString())
            {
                case "A":
                    {
                        fileName = string.Format(FILE_NAME, FileA);
                        onlyA.ForEach(p => sb.AppendLine(string.Format("{0},{1}", p.Key, p.Value)));
                    }
                    break;
                case "B":
                    {
                        fileName = string.Format(FILE_NAME, FileB);
                        onlyB.ForEach(p => sb.AppendLine(string.Format("{0},{1}", p.Key, p.Value)));
                    }
                    break;
                default:
                    {
                        fileName = string.Format(FILE_NAME_AB, FileA, FileB);
                        sb.AppendLine(string.Format(",{0},{1}", FileA, FileB));
                        diff.ForEach(p => sb.AppendLine(string.Format("{0},{1},{2}", p.Key, p.Value, dicB[p.Key])));
                    }
                    break;
            }

            saveFileDialog1.FileName = fileName;
            if (saveFileDialog1.ShowDialog()== System.Windows.Forms.DialogResult.OK)
            {
                FileHelper.WriteFile(saveFileDialog1.FileName,sb.ToString());
                MessageBox.Show("Data has been saved.");
            }
        }
    }
}
